<template>
  <div class="chart-wrapper" :style="{ height }">
    <div v-if="loading" class="chart-loading">
      <div class="spinner"></div>
      <div class="loading-text">加载中...</div>
    </div>
    
    <div v-else-if="!chartData || !chartData.categories || !chartData.series" class="chart-error">
      <i class="fas fa-exclamation-circle"></i>
      <div>数据加载失败</div>
    </div>
    
    <div v-else class="chart-container" ref="chartContainer"></div>
  </div>
</template>

<script>
// 使用ECharts实现图表
// 实际项目中，可以引入echarts或其他图表库
// 此处为简化实现，模拟图表渲染

export default {
  name: 'ChartComponent',
  props: {
    chartData: {
      type: Object,
      default: () => ({})
    },
    chartType: {
      type: String,
      default: 'line'
    },
    height: {
      type: String,
      default: '300px'
    }
  },
  data() {
    return {
      loading: true,
      chart: null
    }
  },
  watch: {
    chartData: {
      handler() {
        this.renderChart()
      },
      deep: true
    },
    chartType() {
      this.renderChart()
    }
  },
  mounted() {
    this.initChart()
  },
  beforeDestroy() {
    if (this.chart) {
      this.chart.dispose()
      this.chart = null
    }
  },
  methods: {
    initChart() {
      // 模拟图表加载
      this.loading = true
      setTimeout(() => {
        this.loading = false
        this.renderChart()
      }, 800)
    },
    
    renderChart() {
      if (this.loading) return
      
      if (!this.chartData || !this.chartData.categories || !this.chartData.series) {
        return
      }
      
      const container = this.$refs.chartContainer
      if (!container) return
      
      // 这里使用Canvas绘制简单图表
      // 实际项目中应使用成熟的图表库如ECharts
      
      // 清空容器
      container.innerHTML = ''
      
      // 创建Canvas元素
      const canvas = document.createElement('canvas')
      canvas.width = container.clientWidth
      canvas.height = container.clientHeight
      container.appendChild(canvas)
      
      const ctx = canvas.getContext('2d')
      
      // 根据图表类型绘制不同图表
      switch (this.chartType) {
        case 'budget':
          this.drawBarChart(ctx, canvas.width, canvas.height)
          break
        case 'expense':
          this.drawPieChart(ctx, canvas.width, canvas.height)
          break
        case 'asset':
          this.drawLineChart(ctx, canvas.width, canvas.height)
          break
        default:
          this.drawBarChart(ctx, canvas.width, canvas.height)
      }
    },
    
    drawBarChart(ctx, width, height) {
      // 绘制简易柱状图
      const categories = this.chartData.categories
      const series = this.chartData.series
      
      if (!categories || !series || series.length === 0) return
      
      const padding = 40
      const chartWidth = width - padding * 2
      const chartHeight = height - padding * 2
      
      // 绘制背景
      ctx.fillStyle = '#f9f9f9'
      ctx.fillRect(0, 0, width, height)
      
      // 绘制标题
      ctx.fillStyle = '#333'
      ctx.font = '14px Arial'
      ctx.textAlign = 'center'
      ctx.fillText('预算执行情况', width / 2, 20)
      
      // 计算最大值以确定比例
      let maxValue = 0
      series.forEach(serie => {
        const serieMax = Math.max(...serie.data)
        maxValue = Math.max(maxValue, serieMax)
      })
      
      // 绘制坐标轴
      ctx.beginPath()
      ctx.moveTo(padding, height - padding)
      ctx.lineTo(width - padding, height - padding)
      ctx.strokeStyle = '#ccc'
      ctx.stroke()
      
      // 绘制数据
      const barWidth = chartWidth / categories.length / (series.length + 1)
      
      series.forEach((serie, serieIndex) => {
        // 为每个系列选择颜色
        const colors = ['#1890ff', '#52c41a', '#fa8c16', '#722ed1']
        ctx.fillStyle = colors[serieIndex % colors.length]
        
        serie.data.forEach((value, index) => {
          const x = padding + (index + 0.5) * (chartWidth / categories.length) + serieIndex * barWidth
          const barHeight = (value / maxValue) * chartHeight
          const y = height - padding - barHeight
          
          ctx.fillRect(x, y, barWidth * 0.8, barHeight)
          
          // 绘制数值
          ctx.fillStyle = '#666'
          ctx.font = '12px Arial'
          ctx.textAlign = 'center'
          ctx.fillText(value, x + barWidth * 0.4, y - 5)
        })
      })
      
      // 绘制分类名称
      ctx.fillStyle = '#666'
      ctx.font = '12px Arial'
      ctx.textAlign = 'center'
      categories.forEach((category, index) => {
        const x = padding + (index + 0.5) * (chartWidth / categories.length)
        ctx.fillText(category, x, height - padding + 15)
      })
      
      // 绘制图例
      series.forEach((serie, index) => {
        const colors = ['#1890ff', '#52c41a', '#fa8c16', '#722ed1']
        const x = padding + index * 80
        const y = 40
        
        ctx.fillStyle = colors[index % colors.length]
        ctx.fillRect(x, y, 15, 15)
        
        ctx.fillStyle = '#666'
        ctx.font = '12px Arial'
        ctx.textAlign = 'left'
        ctx.fillText(serie.name, x + 20, y + 12)
      })
    },
    
    drawPieChart(ctx, width, height) {
      // 绘制简易饼图
      const categories = this.chartData.categories
      const series = this.chartData.series
      
      if (!categories || !series || series.length === 0) return
      
      // 只使用第一个系列的数据
      const data = series[0].data
      const total = data.reduce((sum, value) => sum + value, 0)
      
      // 绘制背景
      ctx.fillStyle = '#f9f9f9'
      ctx.fillRect(0, 0, width, height)
      
      // 绘制标题
      ctx.fillStyle = '#333'
      ctx.font = '14px Arial'
      ctx.textAlign = 'center'
      ctx.fillText('费用类别分布', width / 2, 20)
      
      // 绘制饼图
      const centerX = width / 2
      const centerY = height / 2
      const radius = Math.min(width, height) / 2 - 40
      
      let startAngle = 0
      const colors = ['#1890ff', '#52c41a', '#fa8c16', '#722ed1', '#13c2c2', '#f5222d']
      
      data.forEach((value, index) => {
        const sliceAngle = (value / total) * 2 * Math.PI
        
        ctx.beginPath()
        ctx.moveTo(centerX, centerY)
        ctx.arc(centerX, centerY, radius, startAngle, startAngle + sliceAngle)
        ctx.closePath()
        
        ctx.fillStyle = colors[index % colors.length]
        ctx.fill()
        
        // 绘制标签
        const labelAngle = startAngle + sliceAngle / 2
        const labelX = centerX + Math.cos(labelAngle) * (radius * 0.7)
        const labelY = centerY + Math.sin(labelAngle) * (radius * 0.7)
        
        ctx.fillStyle = '#fff'
        ctx.font = 'bold 12px Arial'
        ctx.textAlign = 'center'
        ctx.textBaseline = 'middle'
        ctx.fillText(value, labelX, labelY)
        
        startAngle += sliceAngle
      })
      
      // 绘制图例
      const legendY = height - 40
      categories.forEach((category, index) => {
        const x = (width / categories.length) * (index + 0.5)
        
        ctx.fillStyle = colors[index % colors.length]
        ctx.fillRect(x - 30, legendY, 15, 15)
        
        ctx.fillStyle = '#666'
        ctx.font = '12px Arial'
        ctx.textAlign = 'left'
        ctx.fillText(category, x - 10, legendY + 12)
      })
    },
    
    drawLineChart(ctx, width, height) {
      // 绘制简易折线图
      const categories = this.chartData.categories
      const series = this.chartData.series
      
      if (!categories || !series || series.length === 0) return
      
      const padding = 40
      const chartWidth = width - padding * 2
      const chartHeight = height - padding * 2
      
      // 绘制背景
      ctx.fillStyle = '#f9f9f9'
      ctx.fillRect(0, 0, width, height)
      
      // 绘制标题
      ctx.fillStyle = '#333'
      ctx.font = '14px Arial'
      ctx.textAlign = 'center'
      ctx.fillText('资产状况趋势', width / 2, 20)
      
      // 计算最大值以确定比例
      let maxValue = 0
      series.forEach(serie => {
        const serieMax = Math.max(...serie.data)
        maxValue = Math.max(maxValue, serieMax)
      })
      
      // 绘制坐标轴
      ctx.beginPath()
      ctx.moveTo(padding, padding)
      ctx.lineTo(padding, height - padding)
      ctx.lineTo(width - padding, height - padding)
      ctx.strokeStyle = '#ccc'
      ctx.stroke()
      
      // 绘制数据
      series.forEach((serie, serieIndex) => {
        const colors = ['#1890ff', '#52c41a', '#fa8c16', '#722ed1']
        const color = colors[serieIndex % colors.length]
        
        ctx.beginPath()
        serie.data.forEach((value, index) => {
          const x = padding + index * (chartWidth / (categories.length - 1))
          const y = height - padding - (value / maxValue) * chartHeight
          
          if (index === 0) {
            ctx.moveTo(x, y)
          } else {
            ctx.lineTo(x, y)
          }
          
          // 绘制数据点
          ctx.fillStyle = color
          ctx.beginPath()
          ctx.arc(x, y, 4, 0, Math.PI * 2)
          ctx.fill()
          
          // 绘制数值
          ctx.fillStyle = '#666'
          ctx.font = '12px Arial'
          ctx.textAlign = 'center'
          ctx.fillText(value, x, y - 15)
        })
        
        ctx.strokeStyle = color
        ctx.stroke()
      })
      
      // 绘制分类名称
      ctx.fillStyle = '#666'
      ctx.font = '12px Arial'
      ctx.textAlign = 'center'
      categories.forEach((category, index) => {
        const x = padding + index * (chartWidth / (categories.length - 1))
        ctx.fillText(category, x, height - padding + 15)
      })
    }
  }
}
</script>

<style scoped>
.chart-wrapper {
  position: relative;
  width: 100%;
  min-height: 200px;
}

.chart-container {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.chart-loading {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background-color: rgba(255, 255, 255, 0.6);
}

.spinner {
  width: 30px;
  height: 30px;
  border: 3px solid rgba(0, 0, 0, 0.1);
  border-top-color: #1890ff;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-bottom: 8px;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.loading-text {
  font-size: 14px;
  color: #666;
}

.chart-error {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #f5222d;
}

.chart-error i {
  font-size: 24px;
  margin-bottom: 8px;
}
</style> 